macro WSYMB chr 
{  
    mov [fs:edi], byte chr
    inc edi
}

macro WSYMW chr 
{
    mov [fs:edi], word chr
    inc edi
    inc edi
}

regbit db 0 ; 0 - не определено, 8,16,32
            ; 1 - mm, 2-st, 3-xmm, 4-seg, 5-cr, 6-dr

dreg32 db 0 ; Значение reg16/32 (0=16, 0xff=32)
dmem32 db 0 ; Значение mem16/32 (0=16, 0xff=32)
dlock  db 0 ; префикс 
drep   db 0
drepnz db 0
dsfx   db 0 ; 0=нет, 1=es, 2=cs, 3=ss, 4=ds, 5=fs, 6=gs

f_modrm db 0 ; оригинал
f_rm    db 0 ; разобранный r/m
f_reg   db 0 ; разобранный reg
f_mod   db 0 ; разобранный mod
rbase   db 0 ; 16 (16 bit), 24 (32 bit) 

data_str_list:

    ; Групповые арифметико-логические инструкции
    db "add",0,"or",0,"adc",0,"sbb",0,"and",0,"sub",0,"xor",0,"cmp",0
    
    ; Регистры
    db "al",0,"cl",0,"dl",0,"bl",0,"ah",0,"ch",0,"dh",0,"bh",0 ; 8..15
    db "ax",0,"cx",0,"dx",0,"bx",0,"sp",0,"bp",0,"si",0,"di",0 ; 16..23
    db "eax",0,"ecx",0,"edx",0,"ebx",0,"esp",0,"ebp",0,"esi",0,"edi",0  ; 24..31   

    ; Сегменты
    db "es",0,"cs",0,"ss",0,"ds",0,"fs",0,"gs",0,"?",0,"?",0 ; 32..39

    ; Указатели в mod/rm
    db "bx+si",0,"bx+di",0,"bp+si",0,"bp+di",0,"si",0,"di",0,"bp",0,"bx",0 ; 40..47
    
    ; Различные инструкции
    ;  48       49      50      51      52      53      54      55
    db "push",0,"pop",0,"daa",0,"das",0,"aaa",0,"aas",0,"inc",0,"dec",0

    ;  56         57       58        59       60       61       62      63
    db "pusha",0,"popa",0,"bound",0,"arpl",0,"imul",0,"idiv",0,"insb",0,"outsb",0

    ;   64       65        66       67       68     69      70       71
    db "insw",0,"outsw",0,"test",0,"xchg",0,"mov",0,"lea",0,"nop",0,"call",0

    ;   72     73     74     75      76     77      78      79
    db "jo",0,"jno",0,"jc",0,"jnc",0,"je",0,"jne",0,"jb",0,"ja",0

    ;   80     81     82     83       84    85      86      87
    db "js",0,"jns",0,"jp",0,"jnp",0,"jl",0,"jnl",0,"jng",0,"jg",0

    ;   88      89       90     91       92        93       94       95
    db "cbw",0,"cwde",0,"cwd",0,"cdq",0,"fwait",0,"pushf",0,"popf",0,"ret",0

    ;  96        97       98           99        100     101       102        103
    db "word ",0,"dword ",0,"qword ",0,"sahf",0,"lahf",0,"movsb",0,"movsw",0,"cmpsb",0

    ;  104        105      106        107       108      109       110        111
    db "cmpsw",0,"stosb",0,"stosw",0,"lodsb",0,"lodsw",0,"scasb",0,"scasw",0,"retf",0

    ;  112      113    114      115    116     117     118      119
    db "rol",0,"ror",0,"rcl",0,"rcr",0,"shl",0,"shr",0,"sal",0,"sar",0

    ;  120      121    122        123      124      125     126      127
    db "les",0,"lds",0,"enter",0,"leave",0,"int3",0,"int",0,"into",0,"iret",0

    ;  128      129     130      131      132       133       134       135
    db "amx",0,"adx",0,"salc",0,"xlat",0,"loopnz",0,"loopz",0,"loop",0,"jcxz",0

    ;  136       137    138      139      140     141          142       143
    db "jecxz",0,"in",0,"out",0,"lock ",0,"rep ",0,"repnz ",0,"al,dx",0,"icebp",0

    ;  144     145     146     147     148      149     150     151
    db "hlc",0,"cmc",0,"not",0,"neg",0,"mul",0,"imul",0,"div",0,"idiv",0

    ;  152      153    154     155     156     157      158    159
    db "clc",0,"stc",0,"cli",0,"sti",0,"cld",0,"std",0,"jmp",0,"dx,al",0

    ;  160             161
    db "<undefined>",0,"byte ",0

    ; Окончание листинга
    db 0

mnemonics_list:

    ; Листинг основных арифмеческих опкодов (0..0x3F)
    dw 0,0,0,0,0,0,48,49, 1,1,1,1,1,1,48,0
    dw 2,2,2,2,2,2,48,49, 3,3,3,3,3,3,48,49
    dw 4,4,4,4,4,4,0,50,  5,5,5,5,5,5,0,51
    dw 6,6,6,6,6,6,0,52,  7,7,7,7,7,7,0,53

    ; INC/DEC/PUSH/POP,IMUL,RJMPB
    ;  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    dw 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55  ; 0x40..0x4F
    dw 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49  ; 0x50..0x5F
    dw 56, 57, 58, 59, 0,  0,  0,  0,  48, 60, 48, 60, 62, 64, 63, 65  ; 0x60..0x6F
    dw 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87  ; 0x70..0x7F
    dw 0,  0,  0,  0,  66, 66, 67, 67, 68, 68, 68, 68, 68, 69, 68, 49  ; 0x80..0x8F
    dw 70, 67, 67, 67, 67, 67, 67, 67, 0,  0,  71, 92, 93, 94, 99, 100 ; 0x90..0xAF
    dw 68, 68, 68, 68, 101,102,103,104,66, 66, 105,106,107,108,109,110 ; 0xA0..0xAF
    dw 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68  ; 0xB0..0xBF
    dw 0,  0,  95, 95, 120,121,68, 68, 122,123,111,111,124,125,126,127 ; 0xС0..0xСF

    ;  0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    dw 0,   0,   0,   0,   128, 129, 130, 131, 0,   0,   0,   0,   0,   0,   0,   0   ; 0xD0..0xDF | FPU
    dw 132, 133, 134, 135, 137, 137, 138, 138, 71,  158, 158, 158, 137, 137, 138, 138 ; 0xE0..0xEF
    dw 0,   143, 0,   0,   144, 145, 0,   0,   152, 153, 154, 155, 156, 157, 0,   0   ; 0xF0..0xFF

grps_mnemonic: 

    db 66, 66, 146, 147, 148, 149, 150, 151 ; GRP3 (0xf6,0xf7)
    db 54, 55, 71, 71, 158, 158, 48, 160    ; GRP4 (0xfe,0xff)

; типы - 0 (invalid opcode)
; ----------------------------------
; 1  - r/m8, r8
; 2  - r/m16/32, r16/32
; 3  - r8, modrm
; 4  - r16/32, modrm
; ---
; 5  - al, i8
; 6  - ax/eax, i16/32
; 7  - сегмент (первые 64)
; 8  - <нет операнда>
; 9  - нижние 3 бита опкода - это операнд ax..di (eax..edi)
; 10 - imm8 (signed ext)
; 11 - imm16/32
; 12 - r16/32, r/m, imm8 (signed ext)
; 13 - r16/32, r/m imm16/32
; 14 - rel8
; ---
; 15 - r/m8, i8
; 16 - r/m16/32, i16/32
; 17 - r/m16/32, i8 (16-32 signed)
; ---
; 18 - r/m/16/32, sreg
; 19 - Sreg, r/m/16/32
; 20 - word/dword ptr [r/m]
; ---
; 21 - ax/eax, <low3bit> (так же, как и id=9)
; 22 - callf <offset16/32>:<segment16>

; Инструкции с MOFFSET
; ---
; 23 - al, [offset16/32]
; 24 - ax/eax, [offset16/32]
; 25 - [offset16/32], al
; 26 - [offset16/32], ax/eax
; ---
; 27 - r8, imm8          >> reg = opcode & 0x07
; 28 - r16/32, imm16/32  >>
; ---
; 29 - r/m/16/32, imm8 (при этом i8 не расширяется)
; 30 - imm16 (всегда 16)
; 31 - imm16/imm8 (ENTER)
; 32 - imm8  (всегда 8)
; ---
; 33 - r/m/8, 1
; 34 - r/m/16/32, 1
; 35 - r/m/8, cl
; 36 - r/m/16/32, cl
; ---
; 37 - rel16/32
; ---
; 38 - ...
; 39 - ax/eax, imm8
; 40 - al, dx
; 41 - ax/eax, dx
; 42 - imm8, al
; 43 - imm8, ax/eax
; 44 - dx, al
; 45 - dx, ax/eax
; --
; 46 - grp3_1
; 47 - grp3_2
; 48 - grp4_1
; 49 - grp4_2
; ----------------------------------

types_list:

    ; Арифметические опкоды
    db 1,2,3,4,5,6,7,7,1,2,3,4,5,6,7,0 ; 0x00
    db 1,2,3,4,5,6,7,7,1,2,3,4,5,6,7,7 ; 0x10
    db 1,2,3,4,5,6,8,8,1,2,3,4,5,6,8,8 ; 0x20
    db 1,2,3,4,5,6,8,8,1,2,3,4,5,6,8,8 ; 0x30

    ; INC/DEC/PUSH/POP инструкции
    db 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9  ; 0x40 | Может быть для x86-64
    db 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9  ; 0x50

    ;  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    ; --------------------------------------------------------------------------
    db 0,  0,  4,  2,  0,  0,  0,  0,  11, 12, 10, 13, 8,  8,  8,  8  ; 0x60
    db 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 ; 0x70
    db 15, 16, 15, 17, 1,  2,  3,  4,  1,  2,  3,  4,  18, 4,  19, 20 ; 0x80
    db 0,  21, 21, 21, 21, 21, 21, 21, 8,  8,  22, 8,  8,  8,  8,  8  ; 0x90
    db 23, 24, 25, 26, 8,  8,  8,  8,  5,  6,  8,  8,  8,  8,  8,  8  ; 0xA0
    db 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28 ; 0xB0
    db 15, 29, 30, 8,  4,  4,  15, 16, 31, 8,  30, 8,  8,  32, 8,  8  ; 0xC0
    db 33, 34, 35, 36, 8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0  ; 0xD0 | 0xD8-0xDF = FPU
    db 14, 14, 14, 14, 5,  39, 42, 43, 37, 37, 22, 14, 40, 41, 44, 45 ; 0xE0
    db 0,  8,  0,  0,  8,  8,  46, 47, 8,  8,  8,  8,  8,  8,  48, 49 ; 0xF0 | F6,F7,FE,FF GRP3/4

    ; ----- Расширенные окподы, обрабатываются отдельно -----
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    db 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0

; Какие операнды имеют ModRM
has_mod_rm:

  ;  0 1 2 3 4 5 6 7 8 9 a b c d e f 
  ;  -------------------------------
  db 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0 ; 00
  db 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0 ; 10
  db 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0 ; 20
  db 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0 ; 30
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 40
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 50
  db 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0 ; 60 
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 70 
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 80 
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 90 
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; A0 
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; B0 
  db 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0 ; C0 
  db 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1 ; D0 
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; E0 
  db 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 ; F0 

  ; Расширенные опкоды mod/rm
  db 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1 ; 0F 00
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F 10
  db 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1 ; 0F 20
  db 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0 ; 0F 30
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F 40
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F 50
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F 60
  db 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1 ; 0F 70
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 0F 80
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F 90
  db 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1 ; 0F A0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F B0
  db 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 ; 0F C0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F D0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 0F E0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 ; 0F F0
